package com.prepare_interview;

import org.apache.commons.io.FileUtils;

import java.io.File;
import java.util.concurrent.CountDownLatch;
import java.util.concurrent.locks.ReentrantLock;

/**
 * 1.帮助理解多线程ReentrantLock的用法，以及主线程等待子线程执行完后
 *   再继续执行。
 * 2.面试打击了我，io流，读取文件缓存问题，可以直接使用封装好的FileUtils，apache.commons.io很多
 *   东西都封装了，举一反三啊，多线程io流要看啊，针对面试
 * Created by WDJ on 2019/12/3.
 */
public class DirSize {

    public static void main(String[] args) throws InterruptedException {
        DirTotalSize dirTotalSize = new DirTotalSize();
        ReentrantLock lock = new ReentrantLock();
        CountDownLatch latch = new CountDownLatch(3);

        new Thread(new TT(dirTotalSize,"E:\\java后台常用软件",lock,latch)).start();
        new Thread(new TT(dirTotalSize,"E:\\java环境", lock, latch)).start();
        new Thread(new TT(dirTotalSize,"E:\\Windows常用软件", lock, latch)).start();
        System.out.println("latch:"+latch.getCount());
        latch.await();
        System.out.println("latch:"+latch.getCount());
        new Thread(new Total(dirTotalSize)).start();
    }
}

class TT implements Runnable {
    private DirTotalSize dirTotalSize;
    private String dirPath;
    private ReentrantLock lock;
    private CountDownLatch latch;

    public TT(DirTotalSize dirTotalSize, String dirPath, ReentrantLock lock, CountDownLatch latch) {
        this.dirTotalSize = dirTotalSize;
        this.dirPath = dirPath;
        this.lock = lock;
        this.latch = latch;
    }

    @Override
    public void run() {
        lock.lock();
        try {
            dirTotalSize.add(FileUtils.sizeOfDirectory(new File(dirPath)));
        } finally {
            latch.countDown(); //减一
            lock.unlock();
        }
    }
}

class Total implements Runnable{
    private DirTotalSize dirTotalSize;

    public Total(DirTotalSize dirTotalSize) {
        this.dirTotalSize = dirTotalSize;
    }

    @Override
    public void run() {
        System.out.println("3个文件夹总大小："+dirTotalSize.getTotalSize());
    }
}

class DirTotalSize {
    private long totalSize;

    public void add(long size){
        totalSize += size;
    }

    public long getTotalSize() {
        return totalSize;
    }
}